import random
from django.db import transaction
from django.shortcuts import render, redirect, HttpResponse
from utils.pager import Pagination
from www import models
from utils.bootstrap import BootStrapForm
from django import forms
from datetime import datetime
from django.db.models import F, Q
from django_redis import get_redis_connection
from utils.video import get_old_view_count
from django.contrib import messages
from django.conf import settings
from django.contrib.messages import constants, utils

def yang_list(request):

    for msg in messages.get_messages(request):
        print(msg)
    queryset = models.Order.objects.all().order_by('-id')
    pager = Pagination(request, queryset)
    return render(request, 'user/yang_list.html', {"pager": pager})


class YangModelForm(BootStrapForm, forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        price_count_list = []
        text_list = []
        queryset = models.PricePolicy.objects.all().order_by('price')
        for each_price_policy in queryset:
            unit_price = each_price_policy.price / each_price_policy.count
            print(unit_price)
            price_count_list.insert(0, (each_price_policy.count, each_price_policy.price))
            text_list.append(f"数量大于等于{each_price_policy.count}时，单价为{round(unit_price, 3)}")
            # self.price_policy += f"{each_price_policy.count}-->{each_price_policy.price}"
            # print(each_price_policy)
        self.fields['count'].help_text = "；".join(text_list)
        self.price_count_list = price_count_list

    class Meta:
        model = models.Order
        fields = ['url', 'count', 'memo']

    def clean_count(self):
        count = self.cleaned_data['count']
        if not self.price_count_list:
            raise forms.ValidationError("请联系管理员设置价格策略")
        min_count = self.price_count_list[-1][0]
        if count < min_count:
            raise forms.ValidationError("数量太少，大车小辆不够油钱，请不要低于{}".format(min_count))
        return count


def yang_add(request):
    origin = request.GET.get("redirect", "/yang/list/")
    if request.method == 'GET':
        form = YangModelForm()
        return render(request, 'user/yang_add.html', {"form": form})
    form = YangModelForm(request.POST)
    if not form.is_valid():
        return render(request, 'user/yang_add.html', {"form": form})
    video_url = form.cleaned_data['url']
    count = int(form.cleaned_data['count'])

    # 1.原视频播放量采集

    status, view_count = get_old_view_count(video_url)
    # if not status:
    #     form.add_error("url", "视频原播放量采集失败")
    #     return render(request, "user/form.html", {"form": form})
    # 创建订单,需要计算出所需扣除的款，oid,订单状态是1-->待执行
    oid = datetime.strftime(datetime.now(), '%Y%m%d%H%M%S') + str(random.randint(10000000, 99999999))
    # 针对订单号进行查重
    while True:
        oid = datetime.strftime(datetime.now(), '%Y%m%d%H%M%S') + str(random.randint(10000000, 99999999))
        exists = models.Order.objects.filter(oid=oid).exists()
        if not exists:
            break

    # 根据用户刷入的数量进行价格的判断，前期生成了一个form.price_count_list,根据这个进行价格生成
    count = int(form.cleaned_data['count'])
    for each_count, each_price in form.price_count_list:
        if count >= each_count:
            total_price = round(each_price / each_count * count, 2)
            break

    # 下面这几个数据库的操作必须得是原子性的，要成功都成功，要失败都失败
    try:
        with transaction.atomic():
            # 这是价格，还得根据用户等级再生成real_price，对账户操作是加锁，防止出错
            cus_obj = models.Customer.objects.filter(id=request.nb_user.id).select_for_update().first()
            real_price = round(total_price * cus_obj.level.percent / 100, 2)
            # 判断实际价格和当前账户价格
            if real_price > cus_obj.balance:
                form.add_error("count", f"账户余额不足，余额：{cus_obj.balance}，当前订单价格：{real_price}")
                return render(request, "user/yang_add.html", {"form": form})
            form.instance.oid = oid
            form.instance.real_price = real_price
            form.instance.price = total_price
            form.instance.charge_type = 3
            form.instance.customer_id = request.nb_user.id
            form.instance.old_view_count = view_count
            form.save()
            # 扣钱
            models.Customer.objects.filter(id=request.nb_user.id).update(balance=F("balance") - real_price)
            # 生成交易记录
            models.TransactionRecord.objects.create(
                charge_type=3,
                customer_id=request.nb_user.id,
                amount=real_price,
                order_oid=oid
            )
            # 将订单号加入队列进行操作
            conn = get_redis_connection()
            conn.lpush('task_queue', oid)
    except Exception as e:
        form.add_error("count", "订单创建失败")
        return render(request, "user/yang_add", {"form": form})
    return redirect(origin)


def yang_cancel(request, pk):

    # 取消订单，也就是撤单操作，操作成功后通过message进行消息展示
    origin = request.GET.get("redirect", "/yang/list/")
    # 获取订单id
    order_obj = models.Order.objects.filter(pk=pk, active=0, customer_id=request.nb_user.id, status=1).first()
    if not order_obj:
        # 说明订单不存在

        messages.add_message(request, settings.MESSAGE_DANDER_TAG, '撤单失败，订单不存在')
        return redirect(origin)
    # 说明订单存在

    return HttpResponse("123")
